Documentation

Demo - 3D Space Shooter - Open Dev Kit Documentation

Open Dev Kit Documentation :: Demo - 3D Space Shooter

2D and 3D physics-based space shooter game utilizing OpenGL and Jolt 3D physics. The game offers both 3D and 2D gameplay modes, but always takes place in a fully 3D space. The goal is to survive waves of enemies, earn points by destroying ships, and collect power-ups to enhance firepower or restore shields. Over time, the game increases in difficulty by introducing stronger enemies and higher spawn rates.

How it Works

  • Game Initialization
      Upon starting the game, the Start function is triggered. This initializes the Gameplay scene, the spaceship's position as well as playing the demo's main music theme. Menu navigation is handled by the TitleScreen keybinds resource set to be the default one in the Tools > Project Options.
  • Mode Selection
      While in the title screen, hovering the cursor over 2D or 3D will switch the camera's perspective by changing the gSideView variable. Then, actual changes to the camera will occur within the variable's Setter script (which executes every time the variable's value is changed) via an Interpolate function at the bottom of the script with "App.Scenes.Gameplay.DefaultCamera.Orientation" set for Expression. Activating either option will trigger the StartGame function, which actually initializes the gameplay by switching scenes (removing the TitleScreen and making the HUD scene visible), switching controls from menu navigation to gameplay, and initializing variables required for gameplay progression like difficulty and the spawn timer.
  • Enemy Spawning
      After a game-mode is selected and the game begins, the gSpawnTimer timer that can be found in Tools > Globals / API is responsible for spawning new enemy spaceships as well as increasing the difficulty over time. This is done by incrementing the gDifficulty variable, or making the gSpawnTimer run more frequently by decreasing its interval, thus increasing its tickrate. Spawned ships and even bullets for that matter, are using the Ship and Bullet classes respectively as a base.

Adding a New Enemy

Follow these steps to add a new spawnable enemy spaceship to the demo:

  1. Add the New Enemy Model:
    1. Open Tools > Resources.
    2. Double-click the Objects sprite-set resource.
    3. Copy either the 2nd or 3rd square tile both of which are enemy ship models, and paste it over to a blank tile. We'll be using that as a base for the new enemy, since we want to keep certain things like collision and the "Destroyed" animation and only change the model.
    4. Click the model on the sequencer view to select it, then hit the delete key to remove it.
    5. Click the Import Images/Model icon to import your graphic model. You may have to configure its scale and rotation.
    6. Now repeat the previous 2 steps for the "Destroyed" pose as well.
  2. Set up the New Enemy Ship:
    1. Open Tools > Globals / API.
    2. Open the "Ships" folder and copy+paste the gEnemySquareShip variable.
    3. Give it a different name and make sure to change its model to the new one by setting Tile to 4 if the new object was created on the 5th tile (the count starts from 0, therefore the 5th tile's # would be 4).
    4. Select the gSpawnTimer variable and double-click its Ticked event to open the script and add the new one as a spawning option.
    5. Somewhere in the middle of the script, you will find a Greater Than (>) branch (found under the General category or by using the search filter) followed by a Less Than (<) branch which is then followed by 2 Change newship functions (found under the App category or by using the search filter).
    6. On the right side of the comparison branches, connect another Less Than (<) branch but set its second value to 50. We want to make it so that there is a 50/50 chance to spawn either a square ship or the new ship, when a round ship isn't chosen for spawning.
    7. Now connect its one side to the Change newship function with a value of "App.Ships.gEnemySquareShip", and a new one with a value of App.Ships.[name of your new ship here].
    8. Make sure the new function is connected to the very next one (Change Interval in this case) so the script continues smoothly.
    9. The updated script should look like this:
  3. Test the Game:
      Run the project to verify the new ship spawns and behaves as expected.

Adding a New Powerup

Follow these steps to add a new spawnable powerup to the demo:

  1. Add the New Powerup Graphic:
    1. Open Tools > Resources.
    2. Double-click the Powerups sprite-set.
    3. Copy the 1st of the 3 existing powerups and paste it over to a blank tile. You can import your own graphic of course or .efkefc file, but in this case we'll be using an existing one which is for shields. It conveniently has the "S" letter for a graphic, which matches the super-speed powerup we want to implement.
    4. Select the effect on the sequencer and on the properties panel set its Color to something fitting, like full yellow.
  2. Set up the New Powerup:
    1. Open Tools > Globals / API.
    2. Open the "Collectables" folder and copy+paste the gHealth variable.
    3. Change its name to gSuper and make sure to change its graphic to the new one by setting Tile to 3 if the new object was created on the 4th tile (the count starts from 0, therefore the 4th tile's # would be 3).
    4. Select SpawnRandomPowerup and click Edit Function Script to add the new powerup as a spawning option.
    5. Somewhere in the middle of the script, you will find 2 Less Than Or Equal (<=) branches followed by Change newpowerup functions.
    6. Add another branch function of the same type on the left side of the first one. We will make it so there's going to be a 50/50 chance of spawning either a health or super-speed powerup:
      • Value 1 = Math.RandomInt(0,100)
      • Value 2 = 50
    7. Now connect its one side to the Change newpowerup function with a value of "Collectables.gHealth._Clone()", and a new one with a value of Collectables.gSuper._Clone().
    8. Make sure the new function is connected to the very next one (Add to Children in this case) so the script continues smoothly.
    9. The updated script should look like this:
  3. Add Functionality (1/2):
    1. Create 3 variables under the "Ship" class.
      • Named mSuperTime of int (integer) type, and a Default value of 0. This will track how many seconds of super-speed the player has left.
      • Named mSuperTimeMax of int (integer) type, and a Default value of 7. This sets the maximum super-speed time in seconds the player will receive upon getting the powerup.
      • Named mSuperTimer of Root.Timer type, set to run every 1 second. This will trigger the script within its Ticked event every second.
    2. Select the gSuper variable again and open the Collision Actor Started event. This will trigger every time the powerup actor collides with another. Since we copied this one from the health powerup one, we only need to do minimal changes to it.
    3. Remove the Change Health function and instead put a Change Max Velocity:
      • Identifier = Ships.gPlayerShip
      • Value = 600 600 400

      The Max Velocity variable has 3 values because it is a 3D vector type variable, meaning it can store up to 3 values. We are changing all 3 values since we want the ship's speed to increase in all directions/axes. The player ship's default velocity values are 300 300 200, so we're essentially doubling its speed with this powerup.
    4. We're adding a Change Acceleration function as well, to make the ship pick up to that higher speed easier:
      • Identifier = Ships.gPlayerShip
      • Value = 80
    5. And the most important part to make this all functioning is setting the "mSuperTime" variable to the set maximum that we're storing in "mSuperTimeMax" with a Change Super Time function:
      • Identifier = Ships.gPlayerShip
      • Value = Ships.gPlayerShip.mSuperTimeMax
    6. It would also be nice to have some visual feedback to have the player know their state has changed. One way to do that is by changing the color of their ship with a Change Tint Color function.
    7. For Identifier use Ships.gPlayerShip, and for color preferably yellow.
    8. The updated script should look like this:
  4. Add Functionality (2/2):
    1. Now select gPlayerShip from the "Ships" folder to edit the Ticked event script of its timer by clicking the Edit Ticked button found in its properties. This will handle when to wear off the super-speed effect powerup.
    2. Add a Greater Than (>) branch for seeing if the player has received the powerup by checking the mSuperTime variable.
      • Value 1 = Ships.gPlayerShip.mSuperTime
      • Value 2 = 0
    3. If mSuperTime is greater than 0, it means the player has recently received the powerup, and since this timer is set to tick every second, we want to reduce that variable by 1 with a Change Super Time on the left path of the branch.
      • Identifier = Ships.gPlayerShip
      • Value = Ships.gPlayerShip.mSuperTime - 1
    4. If mSuperTime isn't greater than 0, it means either the player hasn't received the powerup or it has run out. In that case, we want to revert things back to a normal state.
    5. Change Max Velocity:
      • Identifier = Ships.gPlayerShip
      • Value = 300 300 200
    6. Change Acceleration:
      • Identifier = Ships.gPlayerShip
      • Value = 40
    7. Make sure to revert the ship's color back to normal (white) using the Change Tint Color function.
    8. The script should look like this:
  5. Test the Game:
      Run the project to verify the new powerup spawns and behaves as expected.

If you think anything is missing, please feel free to: submit documentation feedback on this page